#!/usr/bin/env python2
#-*- coding: utf-8 -*-

import json
import os
import sys
import logging
import logging.handlers

import config
from Umpweb.db import api as db_api
from Umpweb import defs

log_map = {}

class NullHandler(logging.Handler):
    def emit(self, record):
        pass

class MessageFilter(logging.Filter):
    '''
    把需要的消息放在DB中, 如果record有skipmf属性就不进行处理
    TODO: 处理数据库异常时可以不影响写入日志文件
    '''
    def filter(self, record):
        if 'skipmf' in dir(record):
            return True

        insert_db = ('WARNING', 'ERROR', 'CRITICAL')
        #insert_db = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
        level = record.levelname

        if level in insert_db:
            #为了防止html的解释
            message = record.getMessage().replace('<', '< ')
            extra = {}
            for i in dir(record):
                if not i.startswith('_'):
                    extra.update({i: str(getattr(record, i))})
            values = {
                    'level': level,
                    'event': record.name,
                    'info': message,
                    'extra': json.dumps(extra),
                    }
            if 'cluster_id' in dir(record):
                values.update({'cluster_id': record.cluster_id})
            db_api.message_create(values)
        return True

def get_log(log_name, logfd=None):
    """
        log_name,日志系统的名字
        return my_logger:
        note:
        如果在配置DEBUG为True，hander的级别为DEBUG，
        否则，配置的级别是INFO
        EVELS = {'debug': logging.DEBUG,
                 'info': logging.INFO,
                 'warning': logging.WARNING,
                 'error': logging.ERROR,
                 'critical': logging.CRITICAL}
    """
    my_logger = log_map.get(log_name)
    if my_logger is not None:
        return my_logger

    log_file = config.main_log
    log_dir = defs.LOG_FOLER
    if not os.path.isdir(log_dir):
        os.makedirs(log_dir, 0755)

    logging.addLevelName(25, "EVENT")
    my_logger = logging.getLogger(log_name)
    if 'DEBUG' in dir(config) and getattr(config, 'DEBUG'):
        my_logger.setLevel(logging.DEBUG)
    else:
        my_logger.setLevel(logging.INFO)

    my_logger.addFilter(MessageFilter())
    handler = logging.handlers.RotatingFileHandler(
        log_file, 
        maxBytes = config.main_log_maxbytes,
        backupCount = config.main_log_backupCount)
    handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter(
            "%(asctime)s-%(name)s-%(levelname)s-%(message)s")
    handler.setFormatter(formatter)
    my_logger.addHandler(handler)

    if not logfd:
        logfd = sys.stdout
    formatter = logging.Formatter('%(asctime)s %(levelname)s [%(name)s] %(message)s')
    ch = logging.StreamHandler(logfd)
    ch.setLevel(logging.DEBUG)
    ch.setFormatter(formatter)
    my_logger.addHandler(ch)

    log_map.update({log_name:my_logger})
    return my_logger

def get_history_log():
    log_name = 'history'

    log_file = config.history_log
    log_dir = os.path.dirname(log_file)
    if not os.path.isdir(log_dir):
        os.makedirs(log_dir, 0755)

    h_logger = log_map.get(log_name)
    if h_logger is not None:
        return h_logger

    h_logger = logging.getLogger(log_name)
    h_logger.setLevel(logging.INFO)
    handler = logging.handlers.RotatingFileHandler(
        log_file,  
        maxBytes = config.history_log_maxbytes,
        backupCount = config.history_log_backupCount)
    handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter(
      "%(asctime)s-%(message)s")
    handler.setFormatter(formatter)
    h_logger.addHandler(handler)
    log_map.update({log_name: h_logger})
    return h_logger

def log_init():
    logging.getLogger("Ump").addHandler(NullHandler())
    logging.getLogger("Ump").addFilter(MessageFilter())


if __name__ == '__main__':
    '''for test'''
    log_init()
    log_a = get_log('log.a')
    log_a_2 = get_log('log.a')
    log_a.info('log_a')
    log_a_2.info('log_a_2')
    log_a.warn('task_fetch error, <Task testvm0001_stop:stoping testvm0001>, No row was found for one()')

